/*
* Copyright 2010 Competentum group
*
* Licensed under the GNU General Public License, Version 3.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.gnu.org/licenses/gpl.html
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.competentum.lib.parser
{
	import mx.core.mx_internal;
	use namespace mx_internal;

	import flash.events.Event;
	import flash.events.EventDispatcher;
	
	import mx.controls.Alert;
	import flash.net.FileReference;
	import flash.events.IOErrorEvent;
	import spark.components.PopUpAnchor;
	import mx.managers.PopUpManager;
	import flash.filesystem.File;
	import flash.filesystem.FileStream;
	import flash.filesystem.FileMode;
	import com.competentum.lib.events.InputOutputDataEvent;

	/**
	 * Performs the full process with saving data to xml-file.
	 * Returns encrypts raw data if encrypter specified.
	 * Shows messages according to current phase.
	 * 
	 * @author Valentine Abanosimov
	 * */
	public class ToFileSaver extends EventDispatcher
	{
		private var alert:Alert;
		private var fileReference:FileReference;
		private var extension:String;
		private var data:String;
		private var file:File;
		private var filePath:String;
		
		public function ToFileSaver(extension:String = '')
		{
			super();
			this.extension = extension;
		}
		
		public function save(data:String, url:String):void
		{
			showSavingAlert();
			saveToFile(data, url);
		}
		
		protected function showSavingAlert():void
		{
			alert = Alert.show('\nSaving to file');
			alert.mx_internal::alertForm.mx_internal::buttons[0].enabled = false;
			alert.mx_internal::alertForm.removeChild(alert.mx_internal::alertForm.mx_internal::buttons[0]);
			var animatedLoader:AnimatedLoader = new AnimatedLoader();
			animatedLoader.x = alert.width / 2 - 11;
			animatedLoader.y = 10;
			alert.mx_internal::alertForm.addChild(animatedLoader);
		}
		
		private function saveToFile(data:String, fileName:String):void
		{
			// save at disk
			fileReference = new FileReference();
			fileReference.addEventListener(Event.COMPLETE, onComplete);
			fileReference.addEventListener(Event.CANCEL, onCancel);
			fileReference.addEventListener(IOErrorEvent.IO_ERROR, onFault);
			
			// open a native save file dialog, using the default file name
			fileReference.save(data, fileName + extension);
			filePath = fileReference.name;
		}
		
		public function saveToFileAIR(data:String, fileName:String):void
		{
			showSavingAlert();
			this.data = data;
			if (fileName == null || fileName == '')
			{
				file = File.applicationStorageDirectory;
				file.addEventListener(Event.SELECT, onAIRSaving);
				file.addEventListener(Event.CANCEL, onCancel);
				file.browseForSave('Select to save');
				return ;
			}
			file = new File(fileName);
			onAIRSaving();
		}
		
		private function onAIRSaving(event:Event = null):void
		{
			filePath = file.nativePath;
			var stream:FileStream = new FileStream();
			stream.open(file, FileMode.WRITE);
			stream.writeUTFBytes(data);
			stream.close();
			onComplete();
		}
		
		protected function onComplete(event:Event = null):void
		{
			// show alert
			removeAlert();
			alert = Alert.show('Saving complete');
			var ioEvent:InputOutputDataEvent = new InputOutputDataEvent(InputOutputDataEvent.SAVED_TO_FILE);
			ioEvent.filePath = filePath;
			dispatchEvent(ioEvent);
		}
		
		protected function onFault(event:IOErrorEvent):void
		{
			// show alert
			removeAlert();
			alert = Alert.show('Can\'t save file');
			dispatchEvent(event.clone());
		}
		
		private function onCancel(event:Event):void
		{
			removeAlert();
			dispatchEvent(event.clone());
		}
		
		/**
		 * Closes alert if needed
		 * */
		protected function removeAlert():void
		{
			if (alert)
			{
				if (alert.isPopUp)
				{
					PopUpManager.removePopUp(alert);
					alert = null;
				}
			}
		}
	}
}